問題來了,為什麼Blazor會知道WeatherForecastService在這裡可以調用?
day03有提到Startup.cs的ConfigureServices的目的就是「設定服務」,Controller把資料回傳這件事情就是一種服務,我們點開Startup.cs,可以在ConfigureServices找到一行程式services.AddSingleton<WeatherForecastService>();
把這行字拿掉,重整網頁,可以看到這樣的錯誤訊息,因為我們試圖在FetchData.razor調用WeatherForecastService,卻沒告訴Blazor我們要註冊這個服務。
不過這並不是day03說到的依賴注入,依賴注入的目的是擺脫高層級程式必須相依於低層級程式的窘境,以減少耦合性。舉例來說,如果今天FetchData.razor要呼叫其他Service例如NewWeatherForecastService的同名方法GetForecastAsync,取回10筆資料,那只要用到WeatherForecastService的地方都必須修改,目前因為範例的關係不多所以沒感覺,如果日後有10幾20幾個地方要改呢?
這時候就是依賴注入發揮功能的時候了,先定義一個介面interface IWeatherForecastService
裡面就寫我們要的方法Task<WeatherForecast[]> GetForecastAsync(DateTime startDate);
也不用實作(雖然介面也不能實作),接著讓WeatherForecastService
跟NewWeatherForecastService
繼承IWeatherForecastService
Startup.cs
改用IWeatherForecastService
跟NewWeatherForecastService
註冊
最後在FetchData.razor
改為注入IWeatherForecastService
重整網頁就能看到資料筆數變為10筆了
依賴注入的核心觀念就是「對某個功能的依賴性是透過注入的方式」,不直接呼叫底層程式,而是呼叫底層程式的介面,即便底層程式更動也不會導致所有呼叫該程式的呼叫端都必須改動。
註:由於筆者是在寫完這篇之後才想起來生命週期,原本想用git rebase的功能回到這一次的commit新增範例,但會有git斷頭疑慮,所以筆者會在day 07再說明生命週期,若有不便敬請見諒。